#include "clientwindow.h"
#include "ui_clientwindow.h"
#include <QFileDialog>
#include <QMessageBox>
#include <QImage>
#include <QPixmap>
#include <vector>
#include <opencv2/imgproc.hpp>

ClientWindow::ClientWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::ClientWindow)
{
    ui->setupUi(this);
    socket = new QTcpSocket(this);

    connect(ui->btnLoadVideo, &QPushButton::clicked, this, &ClientWindow::loadVideo);
    connect(ui->btnConnect, &QPushButton::clicked, this, &ClientWindow::connectToServer);
    connect(socket, &QTcpSocket::readyRead, this, &ClientWindow::readSocket);
    connect(socket, &QTcpSocket::connected, this, []() {
        QMessageBox::information(nullptr, "Connected", "Connected to Server");
    });
    timer = new QTimer(this);
    connect(timer, &QTimer::timeout, this, &ClientWindow::updateFrame);
}

ClientWindow::~ClientWindow() {
    delete ui;
    if (cap.isOpened()) {
        cap.release();
    }
}

void ClientWindow::loadVideo() {
    QString filePath = QFileDialog::getOpenFileName(this, tr("Open Video"), "", tr("Video Files (*.mp4 *.avi *.mov *.mkv)"));
    if (!filePath.isEmpty()) {
        ui->lineEditVideoPath->setText(filePath);
        cap.open(filePath.toStdString());
        if (!cap.isOpened()) {
            QMessageBox::critical(this, "Error", "Failed to open video file.");
            return;
        }
        timer->start(30); // Update frame every 30ms
    }
}

void ClientWindow::connectToServer() {
    socket->connectToHost("127.0.0.1", 12345);
    if (!socket->waitForConnected(3000)) {
        QMessageBox::critical(this, "Error", "Failed to connect to server.");
    }
}

void ClientWindow::updateFrame() {
    cv::Mat frame;
    if (!cap.read(frame)) {
        cap.set(cv::CAP_PROP_POS_FRAMES, 0); // Loop video
        cap.read(frame);
    }

    cv::resize(frame, frame, cv::Size(640, 480));
    cv::cvtColor(frame, frame, cv::COLOR_BGR2RGB); // Convert to RGB for QImage
    QImage qimg(frame.data, frame.cols, frame.rows, frame.step, QImage::Format_RGB888);
    ui->labelVideo->setPixmap(QPixmap::fromImage(qimg));

    // Encode frame to JPEG and send
    std::vector<uchar> buffer;
    cv::imencode(".jpg", frame, buffer, {cv::IMWRITE_JPEG_QUALITY, 95}); // Encode in RGB format
    QByteArray data(reinterpret_cast<const char*>(buffer.data()), buffer.size());
    socket->write(data);
    socket->flush();
}

void ClientWindow::readSocket() {
    QByteArray data = socket->readAll();
    if (!data.isEmpty()) {
        std::vector<uchar> buffer(data.begin(), data.end());
        cv::Mat processedFrame = cv::imdecode(buffer, cv::IMREAD_COLOR);
        if (!processedFrame.empty()) {
            cv::cvtColor(processedFrame, processedFrame, cv::COLOR_BGR2RGB); // Convert to RGB for QImage
            QImage qimg(processedFrame.data, processedFrame.cols, processedFrame.rows, processedFrame.step, QImage::Format_RGB888);
            ui->labelProcessedVideo->setPixmap(QPixmap::fromImage(qimg));
        }
    }
}
